package pl.wroc.uni.ii.evolution.sampleimplementation;

import pl.wroc.uni.ii.evolution.engine.EvAlgorithm;
import pl.wroc.uni.ii.evolution.engine.individuals.EvMessyIndividual;
import pl.wroc.uni.ii.evolution.engine.operators.general.composition.EvTwoOperatorsComposition;
import pl.wroc.uni.ii.evolution.engine.operators.general.display.EvRealtimeToPrintStreamStatistics;
import pl.wroc.uni.ii.evolution.engine.operators.general.replacement.EvBestFromUnionReplacement;
import pl.wroc.uni.ii.evolution.engine.operators.general.selections.EvRouletteSelection;
import pl.wroc.uni.ii.evolution.engine.operators.general.selections.fitness.EvIndividualFitness;
import pl.wroc.uni.ii.evolution.engine.operators.spacespecific.messy.EvMessyCrossover;
import pl.wroc.uni.ii.evolution.engine.operators.spacespecific.messy.EvMessyJumpMutation;
import pl.wroc.uni.ii.evolution.engine.operators.spacespecific.messy.EvMessyReplaceGeneMutation;
import pl.wroc.uni.ii.evolution.engine.prototype.EvTask;
import pl.wroc.uni.ii.evolution.engine.samplealgorithms.EvSGA;
import pl.wroc.uni.ii.evolution.engine.terminationconditions.EvMaxIteration;
import pl.wroc.uni.ii.evolution.objectivefunctions.EvMessyMaxSum;
import pl.wroc.uni.ii.evolution.objectivefunctions.EvMessyObjectiveFunction;
import pl.wroc.uni.ii.evolution.solutionspaces.EvMessySpace;


/**
 * 
 * Example evolutionary algorithm using MessySpace
 * @author Marcin Golebiewski, Krzysztof Sroka
 */

public class EvMessyExample {
  public static void main(String[] args) {


    EvTask evolutionary_task = new EvTask();
    EvAlgorithm<EvMessyIndividual> messyGA = 
      new EvSGA<EvMessyIndividual>(200, 
      new EvRouletteSelection<EvMessyIndividual>(new EvIndividualFitness<EvMessyIndividual>(), 50),
      new EvTwoOperatorsComposition<EvMessyIndividual>(
          new EvMessyReplaceGeneMutation(0.01, 5), 
          new EvTwoOperatorsComposition<EvMessyIndividual>(new EvMessyJumpMutation(0.01), new EvMessyCrossover(1.0))),
      new EvBestFromUnionReplacement<EvMessyIndividual>());
    
    
    EvMessyObjectiveFunction messyFn = new EvMessyObjectiveFunction(5, new EvMessyMaxSum(), 30);
    messyGA.setSolutionSpace(new EvMessySpace(messyFn, 50, 5));
    messyGA.setTerminationCondition(new EvMaxIteration<EvMessyIndividual>(200));
   
    messyGA.addOperator(new EvRealtimeToPrintStreamStatistics<EvMessyIndividual>(System.out));
   
    evolutionary_task.setAlgorithm(messyGA);
    evolutionary_task.run();

    System.out.println("--------------------------------");
    System.out.println("BEST pattern:" + (EvMessyIndividual) messyGA.getBestResult());
    System.out.println("BEST found:" + (EvMessyIndividual) messyGA.getBestResult().best_found_without_empty_genes);
    System.out.println("End value:" + messyGA.getBestResult().best_found_without_empty_genes.getObjectiveFunctionValue());
  }
}
